package org.fire.spring.boot.input.tools;

import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;

public class InputTools {
    public static void click(Robot robot, int delay) {
        robot.mousePress(InputEvent.BUTTON1_MASK);
        robot.mouseRelease(InputEvent.BUTTON1_MASK);
        robot.delay(delay);
    }

    public static void click(Robot robot, int delay, int x, int y) {
        robot.mouseMove(x, y);
        click(robot, delay);
    }

    public static void enter(Robot robot, int delay) {
        key(robot, delay, KeyEvent.VK_ENTER);
    }

    public static void escape(Robot robot, int delay) {
        key(robot, delay, KeyEvent.VK_ESCAPE);
    }

    public static void space(Robot robot, int delay) {
        key(robot, delay, KeyEvent.VK_SPACE);
    }

    public static void tab(Robot robot, int delay) {
        key(robot, delay, KeyEvent.VK_TAB);
    }

    public static void del(Robot robot, int delay) {
        key(robot, delay, KeyEvent.VK_DELETE);
    }

    public static void key(Robot robot, int delay, int keyEvent) {
        robot.keyPress(keyEvent);
        robot.keyRelease(keyEvent);
        robot.delay(delay);
    }

    public static void key(Robot robot, int delay, int keyEvent, int repeat) {
        for (int i = 0; i < repeat; i++) {
            robot.keyPress(keyEvent);
            robot.keyRelease(keyEvent);
        }
        robot.delay(delay);
    }

    public static void hotkey(Robot robot, int delay, int hotKeyEvent, int... keyEvents) {
        robot.keyPress(hotKeyEvent);
        for(int key : keyEvents) {
            robot.keyPress(key);
            robot.keyRelease(key);
        }
        robot.keyRelease(hotKeyEvent);
        robot.delay(delay);
    }

    public static void input(Robot robot, int delay, String ascii) {
        for (int i = 0; i < ascii.length(); i++) {
            int codePoint = ascii.codePointAt(i);
            robot.keyPress(codePoint);
            robot.keyRelease(codePoint);
        }
        robot.delay(delay);
    }

    public static void inputGBK(Robot robot, int delay, String text) throws CharacterCodingException {
        CharsetEncoder encoder = Charset.forName("GBK").newEncoder();
        for (char c : text.toCharArray()) {
            if (Character.isSurrogate(c)) {
                continue;
            }
            if (c >>> 8 == 0) {
                inputGBKByAlt(robot, c);
                continue;
            }
            CharBuffer cb = CharBuffer.wrap(new char[]{c});
            byte[] array = encoder.encode(cb).array();
            assert array.length == 2;
            int code = Byte.toUnsignedInt(array[0]) << 8 | Byte.toUnsignedInt(array[1]);
            inputGBKByAlt(robot, code);
        }
        robot.delay(delay);
    }

    private static void inputGBKByAlt(Robot robot, int gbkCode){
        String s = Integer.toString(gbkCode);
        robot.keyPress(KeyEvent.VK_ALT);
        for (char c : s.toCharArray()) {
            int k = c + 48;
            robot.keyPress(k);
            robot.keyRelease(k);
        }
        robot.keyRelease(KeyEvent.VK_ALT);
    }
}